<template>
  <div class="bpmn-box">
    <el-card class="box-card">
      <OptionBtn @on-export="onExport" @upload-file-res="onUploadFileRes" />
    </el-card>
    <div class="containers">
      <div class="canvas" ref="canvas"></div>
      <div id="js-properties-panel" class="panel"></div>
    </div>
  </div>
</template>

<script>
import propertiesProviderModule from "bpmn-js-properties-panel/lib/provider/camunda";
import OptionBtn from "./component/option-btn";
import BpmnModeler from "bpmn-js/lib/Modeler";
import { xmlStr } from "./mock/xmlStr.js";
import customModule from "./custom";
export default {
  name: "Bpmn-modeler",
  components: {
    OptionBtn,
  },
  mounted() {
    this.init();
  },
  data() {
    return {
      bpmnModeler: null,
      container: null,
      canvas: null,
    };
  },
  methods: {
    init() {
      const canvas = this.$refs.canvas;
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        keyboard: {
          bindTo: window,
        },
        //添加控制板
        propertiesPanel: {
          parent: "#js-properties-panel",
        },
        additionalModules: [
          // 右侧的属性栏
          propertiesProviderModule,
          customModule,
        ],
      });
      this.createNewDiagram(xmlStr);
    },
    // 初始化
    async createNewDiagram(xmlStr) {
      try {
        await this.bpmnModeler.importXML(xmlStr);
        this.bpmnModeler.get("canvas").zoom("fit-viewport");
        this.success();

        this.$message.success("加载完成！");
      } catch (err) {
        this.$message.error(err);
      }
    },
    success() {
      this.addEventBusListener();
    },
    // 获取 节点
    getElement() {
      // 获取全部节点
      let allElement = this.bpmnModeler.get("elementRegistry").getAll();
      // 获取指定ID节点
      // this.bpmnModeler.get("elementRegistry").get(ID);
    },

    /**
     * 修改节点
     * @param {*} id 元素id
     * @param {*} info 需要修改的对象
     */
    updElement(id, info) {
      // 获取修改对象
      const modeling = this.bpmnModeler.get("modeling");
      // 获取元素
      const element = this.bpmnModeler.get("elementRegistry").get(id);
      // 修改
      modeling.updateProperties(element, info);
    },
    // 事件
    addEventBusListener() {
      const that = this;
      const eventBus = that.bpmnModeler.get("eventBus");
      eventBus.on("element.click", function (e) {
        that.elementClick(e);
      });
    },
    // 元素点击
    elementClick(e) {
      if (e.element.type === "bpmn:Process") {
        console.log("点击了 画布 ");
      } else {
        let { $type, id, name } = e.element.businessObject;
        console.table({ $type, id, name });
      }
    },
    onExport(type) {
      if (type === "saveSVG") {
        this.saveSVG();
        return;
      }
      if (type === "saveBPMN") {
        this.saveBPMN();
        return;
      }
    },
    async saveSVG() {
      try {
        const result = await this.bpmnModeler.saveSVG();
        let { err, svg } = result;
        this.downloadFile(svg, "your_process.svg", "image/svg+xml");
      } catch (err) {
        console.log(err);
      }
    },
    async saveBPMN() {
      try {
        const result = await this.bpmnModeler.saveXML({ format: true });
        let { err, xml } = result;
        this.downloadFile(xml, "your_process.bpmn", "application/xml");
      } catch (err) {
        console.log(err);
      }
    },

    // 辅助函数：下载文件
    downloadFile(content, filename, contentType) {
      const blob = new Blob([content], { type: contentType });
      const link = document.createElement("a");
      link.href = window.URL.createObjectURL(blob);
      link.download = filename;
      link.click();
      URL.revokeObjectURL(link.href);
    },

    onUploadFileRes(res) {
      this.createNewDiagram(res);
    },
  },
};
</script>

<style src="./css/app.css"></style>
<style lang="scss" scoped>
.bpmn-box {
}
.containers {
  width: 100%;
  height: 800px;
  background: white;
  overflow: auto;
  background-image: linear-gradient(
      90deg,
      rgba(220, 220, 220, 0.5) 6%,
      transparent 0
    ),
    linear-gradient(rgba(192, 192, 192, 0.5) 6%, transparent 0);
  background-size: 20px 20px;
  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
.canvas {
  width: 100%;
  height: 100%;
}
.panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
}
</style>
